/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ui.gui.documents.toolbox;

import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;

import javax.swing.BorderFactory;
import javax.swing.JScrollPane;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;

import model.AltaRicaConst;
import model.AltaRicaDomain;
import model.altarica_fields.Event;
import model.altarica_fields.Sync;
import model.altarica_fields.Trans;
import model.altarica_fields.Var;
import parser.AltaRicaParseModel;
import parser.AltaRicaParseNode;
import ui.WindowManager;
import ui.gui.documents.AbstractDocument;
import ui.gui.documents.EditorFactory;

import common.AltaRicaModelManager;
import common.AltaRicaModel;
import common.listeners.AltaRicaModelListener;

/**
 *
 * @author stephane
 */
public class AltaricaExplorer extends AbstractToolbox implements MouseListener, AltaRicaModelListener {

    private static AltaricaExplorer _instance = null;
    private static final long serialVersionUID = 1L;
    private ExplorerTreeView _treeView = null;
    private TreeModel _treeModel = null;
    private JScrollPane _scrollPane = null;
    private DefaultMutableTreeNode _root = null;

    public static AltaricaExplorer getInstance() {
        if (_instance == null) {
            _instance = new AltaricaExplorer();
        }
        return _instance;
    }

    private void BrowseAltaRicaNode(DefaultMutableTreeNode treeNode, AltaRicaParseNode node) {

        if (node.getTrans().size() > 0) {
            DefaultMutableTreeNode transNode = new DefaultMutableTreeNode("Trans");
            treeNode.add(transNode);
            for (Trans trans : node.getTrans()) {
                transNode.add(new DefaultMutableTreeNode(trans));
            }
        }

        if (node.getFlows().size() > 0) {
            DefaultMutableTreeNode flowsNode = new DefaultMutableTreeNode("Flows");
            for (Var v : node.getFlows()) {
                flowsNode.add(new DefaultMutableTreeNode(v));
            }
            treeNode.add(flowsNode);
        }

        if (node.getStates().size() > 0) {
            DefaultMutableTreeNode statesNode = new DefaultMutableTreeNode("States");
            for (Var v : node.getStates()) {
                statesNode.add(new DefaultMutableTreeNode(v));
            }
            treeNode.add(statesNode);
        }
        
        if (node.getSyncs().size() > 0) {
            DefaultMutableTreeNode syncNode = new DefaultMutableTreeNode("Sync");
            for (Sync v : node.getSyncs()) {
                syncNode.add(new DefaultMutableTreeNode(v));
            }
            treeNode.add(syncNode);
        }
        
        if (node.getEvents().size() > 0) {
            DefaultMutableTreeNode eventNodes = new DefaultMutableTreeNode("Events");
            for (Event e : node.getEvents()) {
                if (e.isEpsilon() == false) {
                    eventNodes.add(new DefaultMutableTreeNode(e));
                }
            }
            treeNode.add(eventNodes);
        }
    }

    public void refresh() {
        _root.removeAllChildren();



        for (AltaRicaModel model : AltaRicaModelManager.getInstance().getModels()) {
            AltaRicaParseModel ast = model.getAst();
            File f = new File(ast.getFileName());
            DefaultMutableTreeNode fileNode = new DefaultMutableTreeNode(f.getName());
            _root.add(fileNode);

            DefaultMutableTreeNode constNode = new DefaultMutableTreeNode("Constants");
            DefaultMutableTreeNode domainNode = new DefaultMutableTreeNode("Domains");


            for (AltaRicaParseNode node : ast.getNodes()) {
                DefaultMutableTreeNode nodeNode = new DefaultMutableTreeNode(node);
                fileNode.add(nodeNode);
                BrowseAltaRicaNode(nodeNode, node);
            }

            if (ast.getConsts().size() > 0) {
                fileNode.add(constNode);
                for (AltaRicaConst constant : ast.getConsts()) {
                    DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(constant);
                    constNode.add(treeNode);
                }
            }

            if (ast.getDomains().size() > 0) {
                fileNode.add(domainNode);
                for (AltaRicaDomain domain : ast.getDomains()) {
                    DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(domain);
                    domainNode.add(treeNode);
                }
            }

        }
        _treeView.updateUI();
        _treeView.expandAll();


    }

    protected AltaricaExplorer() {

        initComponent();
    }

    private void initComponent() {
        setTitle("Altarica Explorer");

        this._root = new DefaultMutableTreeNode("Model");

        this._treeModel = new DefaultTreeModel(this._root);
        this._treeView = new ExplorerTreeView(this._treeModel);
        this._treeView.addMouseListener(this);
        this._treeView.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        this._treeView.setCellRenderer(new AltaRicaTreeRender());
        this._treeView.setShowsRootHandles(true);
        this._scrollPane = new JScrollPane(this._treeView);

        this.setLayout(new BorderLayout());
        this.add(this._scrollPane, BorderLayout.CENTER);
        this.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/workspaceIcon.png")));
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 2 && _treeView.getSelectionRows().length > 0 && _treeView.getSelectionRows()[0] - 1 > -1) {
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void modelCompiled(String fileName) {
        refresh();
        AbstractDocument newEditor = EditorFactory.getInstance().createFromFile(new File(fileName));
        WindowManager.getInstance().SelectWindow(newEditor);
    }
}
